package com.framework.spring.schedule;

import com.framework.spring.annotations.Component;
import com.framework.spring.domain.ScheduleTask;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

/**
 * @author duanzhizhou
 * @date 2025/4/9
 */
@Component
public class MyScheduler {
    
    private final PriorityBlockingQueue<ScheduleTask> pq = new PriorityBlockingQueue<>();
    
    private final ThreadPoolExecutor executor = new ThreadPoolExecutor(4, 10, 1, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10));
    
    private final Thread mainThread = new Thread(() -> {
        while (true) {
            while (pq.isEmpty()) {
                LockSupport.park();
            }
            if (pq.peek().getDelay() > System.currentTimeMillis()) {
                LockSupport.parkUntil(pq.peek().getDelay());
            } else {
                ScheduleTask st = pq.poll();
                // 队列只对外暴露了offer方法，所以这里poll出来的元素delay一定小于当前时间的
                executor.execute(st.getTask());
                st.setDelay(st.getDelay() + st.getPeriod());
                pq.offer(st);
            }
        }
    });
    
    {
        mainThread.start();
    }
    
    public void addTask(Runnable task, long delay, long period) {
        pq.offer(new ScheduleTask(task, System.currentTimeMillis() + delay, period));
        LockSupport.unpark(mainThread);
    }
    
}
